import Mock from 'mockjs'
import { ElMessage } from 'element-plus'

class MockRequest {
  constructor() {
    this.mockInstance = Mock
    this.setup()
  }

  setup() {
    this.mockInstance.setup({
      timeout: '200-600'
    })
  }

  mockGet(url, mockDataFn) {
    this.mockInstance.mock(url, 'get', (options) => {
      try {
        const data = mockDataFn(options)
        return {
          code: 200,
          message: 'success',
          data
        }
      } catch (error) {
        ElMessage.error('模拟数据生成失败')
        return {
          code: 500,
          message: '模拟数据生成失败',
          data: null
        }
      }
    })
  }

  mockPost(url, mockDataFn) {
    this.mockInstance.mock(url, 'post', (options) => {
      try {
        const requestData = JSON.parse(options.body)
        const data = mockDataFn(requestData)
        return {
          code: 200,
          message: 'success',
          data
        }
      } catch (error) {
        ElMessage.error('模拟数据生成失败')
        return {
          code: 500,
          message: '模拟数据生成失败',
          data: null
        }
      }
    })
  }

  get request() {
    return {
      get: (url, params) => this._mockRequest('get', url, params),
      post: (url, data) => this._mockRequest('post', url, data),
      put: (url, data) => this._mockRequest('put', url, data),
      delete: (url, params) => this._mockRequest('delete', url, params)
    }
  }

  _mockRequest(method, url, data) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        const mockHandler = this._findMockHandler(method, url)
        if (mockHandler) {
          const response = mockHandler({
            url,
            method,
            body: method !== 'get' ? JSON.stringify(data) : undefined,
            query: method === 'get' ? data : undefined
          })
          resolve(response)
        } else {
          reject({
            code: 404,
            message: `未找到 ${url} 的模拟处理器`,
            data: null
          })
        }
      }, Mock.Random.integer(200, 600))
    })
  }

  _findMockHandler(method, url) {
    const mockHandlers = this.mockInstance._mocked
    for (const [key, value] of Object.entries(mockHandlers)) {
      const [mockMethod, mockUrl] = key.split(' ')
      if (
        mockMethod.toLowerCase() === method.toLowerCase() &&
        (mockUrl === url || new RegExp(mockUrl).test(url))
      ) {
        return value
      }
    }
    return null
  }
}

export default new MockRequest()